<script setup name="AttachmentsPicture">

import { Close, Plus } from '@element-plus/icons-vue'
import "vue-cropper/dist/index.css";
import { VueCropper } from "vue-cropper";
import {
  attachmentAdd,
  attachmentDelUrl,
  attachmentDelFileUrl,
  attachmentGetList,
  attachmentGetInfo,
  attachmentUploadPicture
} from "@/api/sys/attachment";
import { dictGetList } from "@/api/sys/dict";
import { getCurrentInstance, reactive } from "vue";

const { proxy } = getCurrentInstance();
const emit = defineEmits()
const props = defineProps({
  idList: [Array, String],
  // 数量限制
  limit: {
    type: Number,
  },
  // 样式
  styleType: {
    type: Boolean,
    default: true
  },
  // 大小限制(MB)
  fileSize: {
    type: Number,
    default: 5,
  },
  // 文件类型, 例如['png', 'jpg', 'jpeg']
  type: {
    type: Array,
    default: () => ["png", "jpg", "jpeg"],
  },
  // 是否显示提示
  isShowTip: {
    type: Boolean,
    default: true
  },
  // 是否直接切图文件直接修改上传
  isCropper: {
    type: Boolean,
    default: false
  }
})

const showTip = computed(
  () => props.isShowTip && (props.type || props.fileSize)
);

const residueNum = computed(
  () => props.limit - pd.requisiteUrls.length
);

const pd = reactive({
  title: "修改图片",
  imgListShow: false,// 图片列表弹窗
  imgShow: false,// 图片详情弹窗
  cutoutShow: false,// 切图弹窗
  controlRemove: false,//是否进行切图了
  dialogImageUrl: '',
  requisiteUrls: [],//勾选图片数组
  urls: [],//图片列表数组
  treeList: [],
  uploadLimit: 5,
  total: 0,
  uploadFiles: [],//上传图片详情数组
  formData: new FormData(),
  CropWidth: 200,// vue-cropper默认生成截图框大小
  CropHeight: 200,
  fileUid: 0,
  queryParams: {
    pageNum: 1,
    pageSize: 14,
    url: null,
    type: null,
    name: null,
    updateTime: null,
    treeId: 108
  },
  form: {
    url: "",
    type: "",
    name: null,
    fileSize: "",
    treeId: null,
    remark: null
  },
})

watch(() => props.idList, val => {
  pd.requisiteUrls = []
  if (!val) {
    pd.requisiteUrls = []
  } else if (typeof (val) != "number") {
    // 首先将值转为数组
    const list = Array.isArray(val) ? val : val.split()
    list.forEach(async (item) => {
      getInfo(item)
    })
  } else {
    getInfo(val)
  }
}, { deep: true, immediate: true });

const options = reactive({
  img: '', // 裁剪图片的地址
  autoCrop: true, // 是否默认生成截图框
  fixedBox: true, // 固定截图框大小 不允许改变
  outputType: "png", // 默认生成截图为PNG格式
  previews: {} //预览数据
});


async function getInfo(id) {
  let queryParams = { id }
  const response = await attachmentGetInfo(queryParams)
  if (response) {
    pd.requisiteUrls.push(response)
  }
}

/**
 * 初始展示样式
 */
//打开列表还是切图弹窗
function handleCropperPicture() {
  if (!props.isCropper) {
    getList()
    getTreeList()
    pd.imgListShow = true
  }

}
//上传样式文件移除
function handleRemoveResList(file) {
  pd.requisiteUrls = pd.requisiteUrls.filter(item => {
    return item.uid != file.uid
  })
  if (props.isCropper) {
    attachmentDelFileUrl(file.url).then(res => {
      proxy.$modal.msgSuccess(res.msg);
    })
  }
  emit('ok', pd.requisiteUrls)
}

/** 
 * 图片列表弹窗 
 */

/** 分类树 */
// 节点单击事件 
function handleTreeNodeClick(res) {
  pd.queryParams.treeId = res.id;
  getList();
}
// 通过条件过滤节点
const filterNode = (value, data) => {
  if (!value) return true;
  return data.label.indexOf(value) !== -1;
};


/** 
 * 展示列表 
 */
// 刷新图片列表
function handleReset() {
  pd.queryParams = {
    pageNum: 1,
    pageSize: 14,
    treeId: 108
  }
  getList()
  getTreeList()
}
// 是否勾选图片
function handleAddCheck(file) {

  if (file.check) {
    file.check = false
    pd.requisiteUrls = pd.requisiteUrls.filter((item) => {
      return item.id != file.id
    })
  } else {
    if (pd.requisiteUrls.length + 1 > props.limit) {
      return proxy.$modal.msgError("选择上限");
    }
    file.check = true
    pd.requisiteUrls.push(file)

  }
  console.log(pd.requisiteUrls);
}
// 是否查看大图
function handlePictureCardPreview(file) {
  pd.dialogImageUrl = file.url
  pd.imgShow = true
}


// 文件删除
function handledeleteFile(file) {
  proxy.$modal.confirm('是否确认删除？').then(() => {
    return attachmentDelUrl(file.url)
  }).then(() => {
    proxy.$modal.msgSuccess("删除成功");
    getList()
  }).catch(() => {
    proxy.$modal.msgError("删除失败");
  });
}

// 传出选择图片
function handleSeletUploads() {
  emit('ok', pd.requisiteUrls)
  pd.imgListShow = false
}

// 文件个数超出
function handleExceed() {
  proxy.$modal.msgError(`上传文件数量不能超过 ${pd.uploadLimit} 个!`);
}

// 上传失败
function handleUploadError() {
  proxy.$modal.msgError("上传文件失败");
  proxy.$modal.closeLoading();
}
// 覆盖默认上传行为
function requestUpload() {
}

// 未上传文件移除
// function removeFile(file) {
//   pd.uploadFiles = pd.uploadFiles.filter(item => {
//     return item.uid != file.uid
//   })
// }
// 图片上传预处理 
function beforeUpload(file) {
  let size = file.size / 1024 / 1024
  if (file.type.indexOf("image/") == -1) {
    proxy.$modal.msgError("文件格式错误，请上传图片类型,如：JPG，PNG后缀的文件。");
  } else if (props.fileSize && size > props.fileSize) {
    proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
  } else {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => {
      options.img = reader.result;
    };

    if (props.isCropper) {
      pd.cutoutShow = true
    }
    else {
      listImgBeforeUpload(file, size)
    }

  }
  pd.fileUid = file.uid
}

//列表上传预处理
function listImgBeforeUpload(file, size) {
  pd.form.type = "img"
  pd.form.uid = file.uid
  pd.form.fileSize = size.toFixed(3)
  pd.form.name = file.name
  pd.cutoutShow = true
}


/** 切图弹窗 */

// 向左旋转
function rotateLeft() {
  proxy.$refs.cropper.rotateLeft();
}

// 向右旋转
function rotateRight() {
  proxy.$refs.cropper.rotateRight();
}

// 图片缩放
function changeScale(num) {
  num = num || 1;
  proxy.$refs.cropper.changeScale(num);
}

// 实时预览
function realTime(data) {
  options.previews = data;
}

// 添加切图图片
function addUploadCropper() {
  if (pd.form.treeId == null) {
    return proxy.$modal.msgError("图片分类不能为空");
  }
  proxy.$refs.cropper.getCropBlob(async img => {
    pd.formData.append("filelist", img);
    proxy.$modal.loading("正在上传文件，请稍候...");
    const response = await attachmentUploadPicture(pd.formData)
    if (props.isCropper) {
      pd.requisiteUrls = []
      pd.requisiteUrls.push({ url: response.urls })
      emit('ok', pd.requisiteUrls)
    } else {
      pd.form.url = response.urls
      const res = await attachmentAdd(pd.form)
      proxy.$modal.msgSuccess(res.msg);
    }
    pd.cutoutShow = false;
    pd.controlRemove = true
    proxy.$modal.closeLoading();
    getList()
  });
}

// 关闭切图窗口
function handleCropperClose() {
  pd.form = {
    url: "",
    type: "",
    name: null,
    fileSize: "",
    treeId: null,
    remark: null
  }
  pd.formData = new FormData()
  if (!pd.controlRemove) {
    pd.urls = pd.urls.filter(item => {
      return item.uid != pd.fileUid
    })
    pd.controlRemove = false
  }
}

/** 初始化数据 */
function getList() {
  attachmentGetList(pd.queryParams).then((res) => {
    if (res.data != undefined) {
      pd.urls = res.data
      pd.total = res.total
      pd.urls.forEach((item) => {
        item.check = false
      })
      if (props.idList != null) {
        pd.requisiteUrls.forEach(element => [
          pd.urls.forEach((item) => {
            if (item.id == element.id) {
              item.check = true
            }
          })
        ])
      }
    } else {
      proxy.$modal.msgError(res.msg);
      pd.urls = []
    }
  })
}
function getTreeList() {
  dictGetList({ ancestors: pd.queryParams.treeId }).then(res => {
    pd.treeList = proxy.handleTree(res.data, 'id', 'parentId', 'children');
  });
}


</script>


<template>
  <div class="attachments">
    <!-- 按钮样式 -->
    <el-button type="primary" icon="PictureFilled" @click="handleCropperPicture" v-if="styleType">
      {{ pd.title }}
    </el-button>
    <!-- 上传样式 -->
    <el-upload v-else v-model:file-list="pd.requisiteUrls" action="#" list-type="picture-card"
      :before-upload="beforeUpload" :disabled="!props.isCropper"
      :class="{ hide: props.limit ? pd.requisiteUrls.length >= props.limit : false }">
      <el-icon @click="handleCropperPicture" style="width: 100%; height: 100%;">
        <Plus />
      </el-icon>
      <template #file="{ file }">
        <div>
          <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
          <span class="el-upload-list__item-actions">
            <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
              <el-icon><zoom-in /></el-icon>
            </span>
            <span class="el-upload-list__item-delete" @click="handleRemoveResList(file)">
              <el-icon>
                <Delete />
              </el-icon>
            </span>
          </span>
        </div>
        <div class="rightCheck" v-show="file.check">
          <el-icon>
            <Check />
          </el-icon>
        </div>
      </template>
      <!-- 上传提示 -->
      <template v-if="showTip" #tip>
        <div>
          请上传
          <template v-if="fileSize">
            大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
          </template>
          <template v-if="type">
            格式为 <b style="color: #f56c6c">{{ type.join("/") }}</b>
          </template>
          的文件
          <template v-if="limit">
            还剩余 <b style="color: #f56c6c">{{ residueNum }}个</b> 可选择
          </template>
        </div>
      </template>
    </el-upload>


    <!-- 图片列表弹窗 -->
    <el-dialog v-model="pd.imgListShow" :title="pd.title" width="778px" @closed="handleSeletUploads">
      <el-row :gutter="20" style="margin-bottom: 15px;">
        <el-col :span="6">
          <el-input clearable v-model="pd.queryParams.name" placeholder="请输入图片名称" prefix-icon="Search" />
        </el-col>
        <el-col :span="2" style="margin-left: 8px;">
          <el-button type="primary" @click="getList">查询</el-button>
        </el-col>
        <el-col :span="3" style="margin-left: 8px;">
          <el-button type="primary" @click="handleReset">重置</el-button>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <!--类别数据-->
        <el-col :span="6">
          <div class="head-container">
            <el-tree :data="pd.treeList" :props="{ label: 'name', children: 'children' }" :expand-on-click-node="false"
              :filter-node-method="filterNode" ref="dictRef" node-key="id" highlight-current default-expand-all
              @node-click="handleTreeNodeClick" />
          </div>
        </el-col>

        <el-col :span="18">
          <el-upload v-model:file-list="pd.urls" action="#" list-type="picture-card" class="listImg"
            :http-request="requestUpload" :before-upload="beforeUpload" :on-exceed="handleExceed"
            :on-error="handleUploadError">
            <el-icon style="width: 100%; height: 100%;">
              <Plus />
            </el-icon>
            <template #file="{ file }">
              <div>
                <img class="el-upload-list__item-thumbnail" style="width: 100px;height: 100px;" :src="file.url" alt="" />
                <span class="text">{{ file.name }}</span>
                <span class="el-upload-list__item-actions">
                  <span class="el-upload-list__item-delete" v-if="!file.check && props.limit"
                    @click="handleAddCheck(file)">
                    <el-icon>
                      <Check />
                    </el-icon>
                  </span>
                  <span class="el-upload-list__item-delete" v-if="file.check && props.limit"
                    @click="handleAddCheck(file)">
                    <el-icon>
                      <Close />
                    </el-icon>
                  </span>
                  <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                    <el-icon><zoom-in /></el-icon>
                  </span>
                  <span class="el-upload-list__item-delete" @click="handledeleteFile(file)">
                    <el-icon>
                      <Delete />
                    </el-icon>
                  </span>
                </span>
              </div>
              <div class="rightCheck" v-show="file.check">
                <el-icon>
                  <Check />
                </el-icon>
              </div>
            </template>

            <template #tip>
              <div class="el-upload__tip">
                请上传
                <template v-if="fileSize">
                  大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
                </template>
                <template v-if="type">
                  格式为 <b style="color: #f56c6c">{{ type.join("/") }}</b>
                </template>
                的文件
                <template v-if="limit">
                  还剩余 <b style="color: #f56c6c">{{ residueNum }}个</b> 可选择
                </template>
              </div>
            </template>
          </el-upload>
        </el-col>
      </el-row>
      <el-row>
        <pagination v-show="pd.total > 0" :total="pd.total" v-model:page="pd.queryParams.pageNum"
          v-model:limit="pd.queryParams.pageSize" @pagination="getList" :page-sizes="[14, 28]" />
      </el-row>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="handleSeletUploads">确定</el-button>
          <el-button @click="pd.imgListShow = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
    <el-dialog v-model="pd.imgShow" width="440px">
      <el-image style="width: 400px; height: 400px" :src="pd.dialogImageUrl" fit="fill" />
    </el-dialog>


    <!-- 切图弹窗 -->
    <el-dialog v-model="pd.cutoutShow" width="800px" append-to-body @closed="handleCropperClose">
      <template #header="{ titleId, titleClass }">
        <el-row :gutter="20" align="middle" style="margin-top:10px">
          <el-col :span="4" :offset="0">
            <h4 :id="titleId" :class="titleClass">截取图片</h4>
          </el-col>
          <el-col :span="4" :offset="0">
            <sapn>截图框宽度为:</sapn>
          </el-col>
          <el-col :span="6" :offset="0">
            <el-input v-model="pd.CropWidth" />
          </el-col>
          <el-col :span="4" :offset="0">
            <sapn>截图框高度为:</sapn>
          </el-col>
          <el-col :span="6" :offset="0">
            <el-input v-model="pd.CropHeight" />
          </el-col>
        </el-row>
        <el-row :gutter="20" align="middle" style="margin-top:10px">
          <el-col :span="2" :offset="0">
            <sapn>分类:</sapn>
          </el-col>
          <el-col :span="6" :offset="0">
            <el-select v-model="pd.form.treeId" placeholder="请选择图片分类">
              <el-option v-for="item in pd.treeList" :key="item.value" :label="item.name" :value="item.id" />
            </el-select>
          </el-col>
          <el-col :span="3" :offset="0">
            <sapn>文件名:</sapn>
          </el-col>
          <el-col :span="5" :offset="0">
            <el-input v-model="pd.form.name" placeholder="请输入文件名" />
          </el-col>
          <el-col :span="2" :offset="0">
            <sapn>备注:</sapn>
          </el-col>
          <el-col :span="6" :offset="0">
            <el-input v-model="pd.form.remark" placeholder="请输入备注" />
          </el-col>
        </el-row>
      </template>
      <el-row>
        <el-col :xs="24" :md="12" :style="{ height: '350px' }">
          <VueCropper ref="cropper" :img="options.img" :info="true" :autoCrop="options.autoCrop"
            :autoCropWidth="pd.CropWidth" :autoCropHeight="pd.CropHeight" :fixedBox="options.fixedBox"
            :outputType="options.outputType" @realTime="realTime" v-if="pd.cutoutShow" />
        </el-col>
        <el-col :xs="24" :md="12" :style="{ height: '350px' }">
          <div class="avatar-upload-preview">
            <img :src="options.previews.url" :style="options.previews.img" />
          </div>
        </el-col>
      </el-row>
      <br />
      <el-row>
        <el-col :lg="2" :md="2">
          <el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
            <el-button>
              选择
              <el-icon class="el-icon--right">
                <Upload />
              </el-icon>
            </el-button>
          </el-upload>
        </el-col>
        <el-col :lg="{ span: 1, offset: 2 }" :md="2">
          <el-button icon="Plus" @click="changeScale(1)"></el-button>
        </el-col>
        <el-col :lg="{ span: 1, offset: 1 }" :md="2">
          <el-button icon="Minus" @click="changeScale(-1)"></el-button>
        </el-col>
        <el-col :lg="{ span: 1, offset: 1 }" :md="2">
          <el-button icon="RefreshLeft" @click="rotateLeft()"></el-button>
        </el-col>
        <el-col :lg="{ span: 1, offset: 1 }" :md="2">
          <el-button icon="RefreshRight" @click="rotateRight()"></el-button>
        </el-col>
        <el-col :lg="{ span: 2, offset: 6 }" :md="2">
          <el-button type="primary" @click="addUploadCropper()">提 交</el-button>
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.avatar-upload-preview {
  border-radius: 0%;
}

.remark {
  position: absolute;
  bottom: 6%;
  left: 60%;
  line-height: 32px;
  text-align: right;
}

.listImg {
  margin-left: 8px;
}



.rightCheck {
  right: -15px;
  top: -6px;
  width: 40px;
  height: 24px;
  background: var(--el-color-success);
  text-align: center;
  transform: rotate(45deg);
  position: absolute;

  i {
    color: #fff;
    font-size: 12px;
    margin-top: 11px;
    transform: rotate(-45deg);
  }
}
</style>
<!-- 覆盖elementUI样式 -->
<style lang="scss">
.hide .el-upload--picture-card {
  display: none;
}

.head-container {
  text-align: "center"
}

.listImg {
  .el-upload-list__item {
    width: 100px !important;
    height: 124px !important;

    .text {
      width: 100px;
      line-height: 20px;
      height: 20px;
      display: block;
      overflow: hidden;
      background: #f6f6f6;
      padding: 0 5px;
      text-align: center;
      position: absolute;
      bottom: -2px;
    }
  }

  .el-upload--picture-card {
    width: 100px !important;
    height: 124px !important;
  }
}

.uploadImg {
  .el-upload-list__item {
    width: 90px !important;
    height: 90px !important;
  }

  .el-upload--picture-card {
    width: 90px !important;
    height: 90px !important;
  }
}
</style>